package Main;

import java.awt.*;
import java.awt.event.*;
import javax.swing.JFrame;

import AI.AiManager;
import AI.NameGenerator;
import Announcements.AnnouncementManager;
import Constructions.ConstructionManager;
import Events.EventHandler;
import FrameWork.*;
import FrameWork.Cursor;
import Items.ItemManager;
import MiscelaneousEntities.MiscManager;
import PostProcessing.OxygenPostProcessing;
import Power.PowerManager;
import Projectiles.ProjectileManager;
import Tasks.TaskManager;
import World.*;


public class SpaceGame extends JFrame implements Runnable,WindowListener
{
	public static final int windowXSize = 1200, windowYSize = 750;
	Thread thread;
	int frameCnt = 0,finalFrameCnt = 0,oxygenCnt = 1;
	long startTime, endTime,framePeriod,time;
	boolean paused = false;
	public boolean gameOver = false;
	Dimension dim;
	Image buffer;
	Graphics g;
	public BackGround backGround;
	public World world;
	public Camera camera;
	public KeyListener input;
	public Cursor cursor;
	public MenuManager menuManager;
	public Resources resources;
	public ConstructionManager constructionManager;
	public AnnouncementManager announcementManager;
	public EventHandler eventHandler;
	public PowerManager powerManager;
	public TaskManager taskManager;
	public AiManager aiManager;
	public ItemManager itemManager;
	public ProjectileManager projectileManager;
	public OxygenPostProcessing oxygenEffects;
	public MiscManager miscManager;
	
	public static void main(String args[])
	{
		EventQueue.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				SpaceGame f = new SpaceGame();
				f.setSize(windowXSize,windowYSize);
				f.setVisible(true);
				f.setLayout(new FlowLayout());
			}
		});
	}
	
	public SpaceGame()
	{
		this.addWindowListener(this);
		startTime = 0;
		endTime = 0;
		framePeriod = 10;
		dim = getSize();
		input = new Input(this);
		addKeyListener(this.input);
		backGround = new BackGround();
		world = new World();
		camera = new Camera(World.worldXSize*10,World.worldYSize*10);
		buffer = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(windowXSize, windowYSize);
		cursor = new Cursor(this);
		menuManager = new MenuManager(this);
		time = System.currentTimeMillis();
		resources = new Resources();
		constructionManager = new ConstructionManager(this);
		announcementManager = new AnnouncementManager();
		NameGenerator.loadNames();
		eventHandler = new EventHandler();
		powerManager = new PowerManager(this);
		taskManager = new TaskManager();
		aiManager = new AiManager(this);
		itemManager = new ItemManager(this);
		projectileManager = new ProjectileManager(this);
		oxygenEffects = new OxygenPostProcessing(this);
		miscManager = new MiscManager(this);
		
		
		Thread thread = new Thread(this);  //this is needs to be last!!!!!
		thread.start();
	}
	
	public void run()
    {
        for (;;)
        {
            startTime = System.currentTimeMillis();
            repaint ();
            try
            {
                endTime = System.currentTimeMillis();
                if (framePeriod- (endTime - startTime)>0)
                    Thread.sleep (framePeriod - (endTime - startTime));
            }
            catch (InterruptedException e)
            {
            }
            update();
        }  
     }

	
	public void paint(Graphics finalBuffer)
	{
		Graphics gfx = buffer.getGraphics();
		
		camera.draw(this,gfx.create(0, 0, 1000, 650));
		gfx.setColor(Color.RED);
		gfx.drawString("FPS: "+finalFrameCnt, 5, 40);
		if (paused())
		{
			gfx.setColor(Color.RED);
			gfx.drawString("PAUSED", windowXSize/2-100, 40);
		}
		menuManager.draw(gfx);
		
		if(gameOver)
		{
			Font gameOverFont = new Font("Arial",Font.PLAIN,200);
			gfx.setFont(gameOverFont);
			gfx.setColor(Color.red);
			gfx.drawString("Game Over", 0, 400);
		}
		
		finalBuffer.drawImage(buffer,0,0,null);
		finalBuffer.setColor(Color.red);
	}
	
	public void update()
	{
		updateFrameCount();
		if(!paused)
		{
			world.updateOxygen();
			constructionManager.update();
			eventHandler.update(this);
			world.updatePower();
			powerManager.update();
			itemManager.update();
			aiManager.update();
			projectileManager.update();
			miscManager.update();
		}
	}
	
	public void windowClosing(WindowEvent e)
	{
		dispose();
		System.exit(0);
	}
	
	public void windowOpened(WindowEvent e)
	{
		
	}
	
	public void windowIconified(WindowEvent e)
	{
		
	}

	public void windowActivated(WindowEvent e) 
	{
		
	}

	public void windowClosed(WindowEvent e) 
	{
		
	}

	public void windowDeactivated(WindowEvent e) 
	{
		
	}

	public void windowDeiconified(WindowEvent e) 
	{
		
	}
	
	private void updateFrameCount()
	{
		frameCnt++;
		if (System.currentTimeMillis() >= time+1000)
		{
			finalFrameCnt = frameCnt;
			frameCnt = 0;
			time = System.currentTimeMillis();
		}
	}
	
	public void setPaused()
	{
		if (paused)
			paused = false;
		else 
			paused = true;
	}
	
	public void setPaused(boolean paused)
	{
		this.paused = paused;
	}
	
	public boolean paused()
	{
		return paused;
	}
}